import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.*;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

import java.util.Locale;

public class Demo extends Application {


    @Override
    public void start(Stage primaryStage) throws Exception {

        // 颜色参考: CustomColorDialog
        double offset;
        Stop[] stops = new Stop[255];
        for (int y = 0; y < 255; y++) {
            offset = 1 - (1.0 / 255) * y;
            int h = (int) ((y / 255.0) * 360);
            stops[y] = new Stop(offset, Color.hsb(h, 1.0, 1.0));
        }

        LinearGradient linearGrad = new LinearGradient(1, 0, 0, 0, true, CycleMethod.NO_CYCLE, stops);
        Rectangle rectangle = new Rectangle(300, 20);
        rectangle.setFill(linearGrad);

        MyPane myPane = new MyPane();

        // Test
        Circle circle = new Circle(40);

        VBox vBox = new VBox(myPane, rectangle, circle);
        vBox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
        vBox.setSpacing(20);
        vBox.setAlignment(Pos.CENTER);


        rectangle.setOnMouseMoved(event -> {
            hue.set(clamp(event.getX() / rectangle.getWidth()) * 360);
        });

        myPane.setOnMouseMoved(event -> {
            saturation.set(clamp(event.getX() / myPane.getWidth()));
            brightness.set(1 - (clamp(event.getY() / myPane.getHeight())));
            Color color = Color.hsb(hue.getValue(), saturation.get(), brightness.get());
            System.out.printf("hue : %s , saturation : %s , : brightness : %s %n", hue.get(), saturation.get(), brightness.get());
            System.out.printf("R : %s , G: %s , B: %s , A : %s %n", color.getRed() * 255, color.getGreen() * 255, color.getBlue() * 255, color.getOpacity());
            System.out.printf("HEX : %s %n", color.toString().replace("0x", "#"));
            circle.setFill(color);
        });

        Scene scene = new Scene(new StackPane(vBox), 400, 400);
        // Scene scene = new Scene(new StackPane(new ColorPicker()), 400, 400);
        primaryStage.setTitle("My JavaFX Application");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    static double clamp(double value) {
        return value < 0 ? 0 : value > 1 ? 1 : value;
    }

    //
    private DoubleProperty hue = new SimpleDoubleProperty(0);
    private DoubleProperty saturation = new SimpleDoubleProperty(1);
    private DoubleProperty brightness = new SimpleDoubleProperty(1);

    public class MyPane extends StackPane {

        private final Rectangle rectangle1;
        private final Rectangle rectangle2;
        private final Rectangle rectangle3;

        public MyPane() {
            setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
            rectangle1 = new Rectangle(300, 200);
            rectangle1.fillProperty().bind(Bindings
                    .createObjectBinding(() -> Color.hsb(hue.getValue(), 1, 1), hue));

            rectangle2 = new Rectangle(300, 200);
            LinearGradient linearGradient1 =
                    new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE,
                            new Stop(0, Color.rgb(255, 255, 255, 1)), new Stop(1, Color.rgb(255, 255, 255, 0)));
            rectangle2.setFill(linearGradient1);
            rectangle3 = new Rectangle(300, 200);
            LinearGradient linearGradient2 =
                    new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE,
                            new Stop(0, Color.rgb(0, 0, 0, 0)), new Stop(1, Color.rgb(0, 0, 0, 1)));
            rectangle3.setFill(linearGradient2);

            getChildren().addAll(rectangle1, rectangle2, rectangle3);
        }


    }

}
